package com.pwt.service;

import com.pwt.common.CustomException;
import com.pwt.common.ResultCode;
import com.pwt.entity.*;
import com.pwt.model.AbilityLineModel;
import com.pwt.model.MachineManageModel;
import com.pwt.model.TreeModel;
import com.pwt.repository.*;
import com.pwt.security.utils.JWTUser;
import com.pwt.security.utils.JWTUtils;
import com.querydsl.core.types.Projections;
import com.querydsl.jpa.impl.JPAQueryFactory;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;

/**
 * AbilityLine service层
 *
 * @author auto generated
 * @date 2021-10-08 11:03:30
 */
@Service
@Transactional(rollbackFor = Exception.class)
public class AbilityLineService {

    private AbilityLineRepository abilityLineRepository;

    private HierarchyRepository hierarchyRepository;

    private JPAQueryFactory jpaQueryFactory;

    private HierarchyService hierarchyService;

    private AbilityHierarchyRepository abilityHierarchyRepository;

    private RoleRepository roleRepository;

    private RoleMachineRepository roleMachineRepository;

    private MASCHINERepository maschineRepository;

    public AbilityLineService(AbilityLineRepository abilityLineRepository, HierarchyRepository hierarchyRepository, JPAQueryFactory jpaQueryFactory, HierarchyService hierarchyService, AbilityHierarchyRepository abilityHierarchyRepository, RoleRepository roleRepository, RoleMachineRepository roleMachineRepository, MASCHINERepository maschineRepository) {
        this.abilityLineRepository = abilityLineRepository;
        this.hierarchyRepository = hierarchyRepository;
        this.jpaQueryFactory = jpaQueryFactory;
        this.hierarchyService = hierarchyService;
        this.abilityHierarchyRepository = abilityHierarchyRepository;
        this.roleRepository = roleRepository;
        this.roleMachineRepository = roleMachineRepository;
        this.maschineRepository = maschineRepository;
    }

    public List<AbilityLine> getList(){
        String username = JWTUtils.getToken().getUsername();
        List<AbilityLine> list = this.abilityLineRepository.findByCreateBy(username);
        AbilityLine abilityLine = new AbilityLine();
        abilityLine.setName("所有");
        list.add(0,abilityLine);
        return list;
    }


    public AbilityLine  update(AbilityLine abilityLinePo) throws CustomException {
        String id = abilityLinePo.getId();
        String name = abilityLinePo.getName();
        String[] ids = abilityLinePo.getIds();

        AbilityLine abilityLine = null;
        if(id  == null){
            abilityLine = new AbilityLine();
        }else{
            abilityLine = this.abilityLineRepository.findById(id).orElse(null);
            if(abilityLine == null){
                throw  new CustomException("未查到数据！");
            }
        }
        AbilityLine byName= this.abilityLineRepository.findByName(name);
        if(byName != null && byName.getId() != abilityLine.getId()){
            throw  new CustomException("名称重复！");
        }
        abilityLine.setName(name);
        abilityLine = this.abilityLineRepository.save(abilityLine);
        this.abilityHierarchyRepository.deleteByAbilityLineId(abilityLine.getId());
        for (String hierarchyId:ids){
            this.abilityHierarchyRepository.save(new AbilityHierarchy(null,abilityLine.getId(),hierarchyId));
        }
        return abilityLine;
    }


    public void  getHierarchy(String[] ids,String id,String pid,List<TreeModel> list){
        if(list != null){
            for (TreeModel tree:list) {
                if(ids != null && ids.length > 0 ){
                    for (String hiId:ids) {
                        if(tree.getId().equals(hiId)){
                            Hierarchy hierarchy = new Hierarchy();
                            hierarchy.setNumber(tree.getId());
                            hierarchy.setName(tree.getName());
                            hierarchy.setNumberName(tree.getNumber());
                            hierarchy.setAbilityLineId(id);
                            if(pid != null){
                                hierarchy.setPid(pid);
                            }
                            hierarchy = this.hierarchyRepository.save(hierarchy);
                            if(tree.getChildren() != null && tree.getChildren().size() > 0 ){
                                getHierarchy(ids,id,hierarchy.getId(),tree.getChildren());
                            }
                        }
                    }
                }
            }
        }
    }

    public AbilityLineModel<Integer> getById(String id) throws CustomException {
        AbilityLineModel abilityLineModel = new AbilityLineModel();
        AbilityLine abilityLine = this.abilityLineRepository.findById(id).orElse(null);
        if(abilityLine == null){
            throw new CustomException(ResultCode.DATA_NOT_FOUND);
        }
        abilityLineModel.setAbilityLine(abilityLine);

        List<Hierarchy> hierarchyList = this.hierarchyRepository.findByAbilityLineId(id);
        List<Integer> hList = new ArrayList<>();
        for (Hierarchy hierarchy: hierarchyList){
            hList.add(hierarchy.getNumber());
        }
        abilityLineModel.setList(hList);
        return abilityLineModel;
    }

    /**
     * 获取用户配置所有的工序和机器
     * @return
     */
    public List<TreeModel> getHierarchySelect(){
        String username = JWTUtils.getToken().getUsername();
        Set<Role> roles = roleRepository.findByUsername(username);
        QRoleMachine qRoleMachine = QRoleMachine.roleMachine;
        QMASCHINE qMachine = QMASCHINE.mASCHINE;
        HashSet<Integer> list = new HashSet<>();
        for (Role r:roles) {
            List<Integer> maschineList = jpaQueryFactory.select(qMachine.mAMASCHINE).from(qRoleMachine).leftJoin(qMachine).on(qRoleMachine.machineId.eq(qMachine.mAMASCHINE))
                    .where(qRoleMachine.roleId.eq(r.getId())).fetch();
            list.addAll(maschineList);
        }
        List<MachineManageModel> machineList= this.maschineRepository.queryMachineByMachineIds(list);
        HashSet<Integer> prueferSet= new HashSet<>();
        for (MachineManageModel machineManageModel:machineList) {
            prueferSet.add(machineManageModel.getPId());
        }

        List<TreeModel> oneList = new ArrayList<>();
        for (Integer pId:prueferSet) {
            List<TreeModel> twoList = new ArrayList<>();
            TreeModel oneTree = new TreeModel();
            for (MachineManageModel machineManageModel:machineList) {
                if(pId != null && pId.equals(machineManageModel.getPId())){
                    if(oneTree.getId() == null && pId.equals(machineManageModel.getPId())){
                        oneTree.setName(machineManageModel.getPName());
                        oneTree.setId(machineManageModel.getPId());
                        oneTree.setNumber(machineManageModel.getPNumber());
                    }
                    TreeModel twoTree = new TreeModel();
                    twoTree.setId(machineManageModel.getMId());
                    twoTree.setNumber(machineManageModel.getMNumber());
                    twoTree.setName(machineManageModel.getMName());
                    twoTree.setPid(pId);
                    twoList.add(twoTree);
                }
            }
            oneTree.setChildren(twoList);
            oneList.add(oneTree);
        }
        return oneList;
//        List<Hierarchy> hierarchies = this.hierarchyRepository.findAll();
//        return this.hierarchyService.queryHierarchyOnTree(hierarchies);
    }

    //在线集合删除
    public void deleteAbility(String id){
        this.hierarchyRepository.deleteByAbilityLineId(id);
        this.abilityLineRepository.deleteById(id);
    }

    public List<Hierarchy> queryAllHierarchy(){
        List<Hierarchy> hierarchyList = this.hierarchyRepository.findAll();
        List<Hierarchy> result = new ArrayList<>();
        for (Hierarchy h:hierarchyList){
            if(h.getPid() == null){
                h.setChildren(this.hierarchyService.queryTree(h,hierarchyList));
                result.add(h);
            }
        }
        return result;
    }

    public List<Hierarchy> queryHierarchyByAbilityLineId(String abilityLineId){
        QHierarchy qHierarchy = QHierarchy.hierarchy;
        QAbilityHierarchy qAbilityHierarchy = QAbilityHierarchy.abilityHierarchy;
        List<Hierarchy> hierarchyList = this.jpaQueryFactory.select(Projections.bean(Hierarchy.class,qHierarchy.id,qHierarchy.name,qHierarchy.number,qHierarchy.pid))
                .from(qHierarchy).leftJoin(qAbilityHierarchy).on(qHierarchy.id.eq(qAbilityHierarchy.hierarchyId)).where(qAbilityHierarchy.abilityLineId.eq(abilityLineId))
                .fetch();
        List<Hierarchy> result = new ArrayList<>();
        for (Hierarchy h:hierarchyList){
            if(h.getPid() == null){
                h.setChildren(this.hierarchyService.queryTree(h,hierarchyList));
                result.add(h);
            }
        }
        return result;
    }

}
